package top.qingyunge.autumn.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import top.qingyunge.autumn.annotation.DatabaseConnect;
import top.qingyunge.autumn.config.DruidConfig.DataSourceContextHolder;

import java.lang.reflect.Method;

@Slf4j
@Aspect
@Component
@Order(1) // 设置切面优先级，确保在事务等切面之前执行
public class DataSourceAspect {


    /**
     * 环绕通知：在方法执行前后切换数据源
     */
    @Around("@annotation(top.qingyunge.autumn.annotation.DatabaseConnect)")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        // 获取方法上的 @DS 注解
        Method method = ((MethodSignature) point.getSignature()).getMethod();
        DatabaseConnect methoodDatabaseConnect = method.getAnnotation(DatabaseConnect.class);

        if (methoodDatabaseConnect != null) {
            DataSourceContextHolder.setDataSourceKey(methoodDatabaseConnect.value());
            log.info("AOP 切换数据源: {}", methoodDatabaseConnect.value());
        } else {
            Class<?> clazz = point.getTarget().getClass();
            DatabaseConnect databaseConnect = clazz.getAnnotation(DatabaseConnect.class);
            if (databaseConnect != null) {
                DataSourceContextHolder.setDataSourceKey(databaseConnect.value());
                log.info("AOP 切换类级数据源: {}", databaseConnect.value());
            }
        }

        try {
            return point.proceed(); // 执行目标方法
        } finally {
            // 方法执行后清除数据源，防止内存泄漏和线程复用问题
            DataSourceContextHolder.clearDataSourceKey();
        }
    }
}